/**
 * Copyright (C) 2012 Oleg Anastassov <o.anastasov@gmail.com>
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kz.kstu.ent.desktop.ui.page;

import kz.kstu.ent.app.delegate.api.ExamDelegate;
import kz.kstu.ent.app.delegate.api.ResultSheetDelegate;
import kz.kstu.ent.app.delegate.impl.ExamDelegateImpl;
import kz.kstu.ent.app.delegate.impl.ResultSheetDelegateImpl;
import kz.kstu.ent.business.entity.Exam;
import kz.kstu.ent.business.entity.ResultSheet;
import kz.kstu.ent.business.entity.Student;
import kz.kstu.ent.desktop.chart.graph.TimeAverageGraph;
import kz.kstu.ent.desktop.chart.info.ChartInfo;
import kz.kstu.ent.desktop.common.DatasetConverter;
import kz.kstu.ent.desktop.images.GUIFactory;
import kz.kstu.ent.desktop.images.GUIIcon;
import kz.kstu.ent.desktop.ui.dialog.card.ResultSheetHelper;
import kz.kstu.ent.util.DateUtil;
import kz.kstu.ent.util.NumberUtil;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

import javax.swing.*;
import java.awt.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * Date: 01.09.12
 * Time: 21:20
 *
 * @author Oleg Anastassov
 */
public class DashboardPage {

    private JPanel rootPanel;
    private JPanel chartPanel;
    private JPanel lastInfoPanel;
    private JPanel averageResultsPanel;
    private JLabel lastDateLabel;
    private JLabel lastAverageResultLabel;
    private JLabel lastBestResultLabel;
    private JLabel lastWorstResultLabel;
    private JLabel theBestResultLabel;
    private JLabel theWorstResultLabel;
    private JLabel theAverageResultLabel;

    private boolean showChart;

    public DashboardPage() {
    }

    public void initData() {

        updateAverageStatistic(); // right panel

        ExamDelegate delegate = new ExamDelegateImpl();
        List<Exam> exams = delegate.findAll(Exam.class);

        DatasetConverter converter = new DatasetConverter();
        final TimeSeriesCollection dataset = converter.convertExams(exams);

        TimeAverageGraph graph = new TimeAverageGraph(
                new ChartInfo(
                        "График среднего значения итогового балла",
                        null,
                        "Средний балл"
                ),
                dataset
        );
        JFreeChart dashboardGraph = graph.build();

        chartPanel.setLayout(new BorderLayout());
        ChartPanel cp = new ChartPanel(dashboardGraph);
        chartPanel.add(cp, BorderLayout.CENTER);
        chartPanel.validate();
    }

    public JPanel getRootPanel() {
        return rootPanel;
    }

    @Deprecated
    private JFreeChart createTimeChart() {
        TimeSeries ts = new TimeSeries("df", Day.class);
        ts.add(new Day(DateUtil.parseDate("05.09.2012", DateUtil.SIMPLE_DATE_PATTERN)), 85);
        ts.add(new Day(DateUtil.parseDate("10.09.2012", DateUtil.SIMPLE_DATE_PATTERN)), 87);
        ts.add(new Day(DateUtil.parseDate("01.10.2012", DateUtil.SIMPLE_DATE_PATTERN)), 101);
        ts.add(new Day(DateUtil.parseDate("11.10.2012", DateUtil.SIMPLE_DATE_PATTERN)), 90);
        ts.add(new Day(DateUtil.parseDate("15.10.2012", DateUtil.SIMPLE_DATE_PATTERN)), 94);
        ts.add(new Day(DateUtil.parseDate("10.11.2012", DateUtil.SIMPLE_DATE_PATTERN)), 105);
        ts.add(new Day(DateUtil.parseDate("14.11.2012", DateUtil.SIMPLE_DATE_PATTERN)), 111);
        ts.add(new Day(DateUtil.parseDate("21.11.2012", DateUtil.SIMPLE_DATE_PATTERN)), 98);
        ts.add(new Day(DateUtil.parseDate("01.12.2012", DateUtil.SIMPLE_DATE_PATTERN)), 99);
        ts.add(new Day(DateUtil.parseDate("05.12.2012", DateUtil.SIMPLE_DATE_PATTERN)), 104);
        ts.add(new Day(DateUtil.parseDate("10.12.2012", DateUtil.SIMPLE_DATE_PATTERN)), 81);
        ts.add(new Day(DateUtil.parseDate("01.01.2013", DateUtil.SIMPLE_DATE_PATTERN)), 78);
        ts.add(new Day(DateUtil.parseDate("08.01.2013", DateUtil.SIMPLE_DATE_PATTERN)), 100);
        ts.add(new Day(DateUtil.parseDate("18.01.2013", DateUtil.SIMPLE_DATE_PATTERN)), 115);

        TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(ts);

        JFreeChart chart = ChartFactory.createTimeSeriesChart(
                "Среднее значение итогового балла", // title
                "Дата проведения пробного ЕНТ", // x-axis label
                "Среднее количество баллов", // y-axis label
                dataset, // data
                false, // create legend?
                false, // generate tooltips?
                false // generate URLs?
        );
        chart.setBackgroundPaint(new Color(214, 217, 223));

        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
//        plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
//        plot.setDomainCrosshairVisible(true);
//        plot.setRangeCrosshairVisible(true);
        XYItemRenderer r = plot.getRenderer();
        if (r instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
            renderer.setBaseShapesVisible(true);
            renderer.setBaseShapesFilled(true);
        }
        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setDateFormatOverride(new SimpleDateFormat("dd-MMM-yyyy"));
        axis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());
        return chart;
    }

    private void updateAverageStatistic() {
        ResultSheetDelegate delegate = new ResultSheetDelegateImpl();
        List<ResultSheet> sheets = delegate.findAll(ResultSheet.class);

        if (sheets.size() == 0) {
            theBestResultLabel.setText("[здесь могла быть ваша фамилия]");
            theBestResultLabel.setIcon(
                    GUIFactory.getIcon(GUIIcon.STAR)
            );
            theWorstResultLabel.setText("[здесь могла быть ваша фамилия]");
            theWorstResultLabel.setIcon(
                    GUIFactory.getIcon(GUIIcon.STOP)
            );
            theAverageResultLabel.setText("<ни одного тестирования еще не проводилось>");
            theAverageResultLabel.setIcon(
                    GUIFactory.getIcon(GUIIcon.CLASS)
            );
            showChart = false;
            return;
        }

        Student bestStudent = new Student();
        Student worstStudent = new Student();

        double average = 0;
        int best = Integer.MIN_VALUE;
        int worst = Integer.MAX_VALUE;
        ResultSheetHelper helper = new ResultSheetHelper();
        for (ResultSheet rs : sheets) {
            int sum = helper.getSumAll(rs);
            if (sum >= best) {
                best = sum;
                bestStudent = rs.getStudent();
            }

            if (sum < worst) {
                worst = sum;
                worstStudent = rs.getStudent();
            }

            average += sum;
        }

        average /= sheets.size();

        // update label values
        DecimalFormat f = new DecimalFormat("000");
        theBestResultLabel.setText(
                f.format(best) + " [" + bestStudent.getSurname() + " " + bestStudent.getName() + "]"
        );
        theBestResultLabel.setIcon(
                GUIFactory.getIcon(GUIIcon.STAR)
        );

        theWorstResultLabel.setText(
                f.format(worst) + " [" + worstStudent.getSurname() + " " + worstStudent.getName() + "]"
        );
        theWorstResultLabel.setIcon(
                GUIFactory.getIcon(GUIIcon.STOP)
        );

        theAverageResultLabel.setText(NumberUtil.formatDouble(average));
        theAverageResultLabel.setIcon(
                GUIFactory.getIcon(GUIIcon.CLASS)
        );

        showChart = true;

    }

}
